home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-26 | 49.9 KB | 1,864 lines |
- Xref: bloom-picayune.mit.edu comp.windows.x.motif:13661 news.answers:4512
- Newsgroups: comp.windows.x.motif,news.answers
- Path: bloom-picayune.mit.edu!enterpoop.mit.edu!news.media.mit.edu!micro-heart-of-gold.mit.edu!wupost!uunet!munnari.oz.au!manuel.anu.edu.au!csc.canberra.edu.au!news
- From: jan@ise.canberra.edu.au (Jan Newmarch)
- Subject: Motif FAQ (Part 5 of 5)
- Message-ID: <1992Dec10.001649.10616@csc.canberra.edu.au>
- Followup-To: comp.windows.x.motif
- Keywords: FAQ question answer
- Sender: news@csc.canberra.edu.au
- Reply-To: jan@ise.canberra.edu.au (Jan Newmarch)
- Organization: University of Canberra
- Date: Thu, 10 Dec 92 00:16:49 GMT
- Approved: news-answers-request@MIT.Edu
- Expires: +1 months
- Lines: 1847
-
- Archive-name: motif-faq/part5
- Last-modified: Thu December 12 1992
- Version: 2.12
-
-
-
- -----------------------------------------------------------------------------
- Subject: 121) TOPIC: MISCELLANEOUS
-
- -----------------------------------------------------------------------------
- Subject: 122)+ What is the matter with Frame in Motif 1.2?
-
- [Last modified: November 92]
-
- Answer: This announcement has been made by OSF:
-
- "IMPORTANT NOTICE
-
- We have discovered two problems in the new 1.2 child alignment resources in
- XmFrame. Because some vendors may have committed, or are soon to commit to
- field releases of Motif 1.2 and 1.2.1, OSF's options for fixing them are
- limited. We are trying to deal with these in a way that does not cause
- hardship for application developers who will develop applications against
- various point versions of Motif. OSF's future actions for correction are
- summarized.
-
- WHAT YOU SHOULD DO AND KNOW
-
- 1. Mark the following change in your documentation.
-
- On page 1-512 of the OSF/Motif Programmer's Reference, change the descriptions
- under XmNchildVerticalAlignment as follows (what follows is the CORRECT
- wording to match the current implementation):
-
- XmALIGNMENT_WIDGET_TOP
- Causes the BOTTOM edge of the title area to align
- vertically with the top shadow of the Frame.
-
- XmALIGNMENT_WIDGET_BOTTOM
- Causes the TOP edge of the title area to align
- vertically with the top shadow of the Frame.
-
- 2. Note the following limitation on resource converters for Motif 1.2 and
- 1.2.1 implementations.
-
- The rep types for XmFrame's XmNentryVerticalAlignment resource were
- incorrected implemented, which means that converters will not work properly.
- The following resource settings will not work from a resource file in 1.2 and
- 1.2.1:
-
- *childVerticalAlignment: alignment_baseline_bottom
- *childVerticalAlignment: alignment_baseline_top
- *childVerticalAlignment: alignment_widget_bottom
- *childVerticalAlignment: alignment_widget_top
-
- If you wish to set these values for these resources (note they are new
- constraint resources in XmFrame) you will have to set them directly in C or
- via uil.
-
- WHAT WE WILL DO
-
- The problem described in note #1 above will not be fixed in the OSF/Motif
- implementation until the next MAJOR release of Motif. At that time we will
- correct the documentation and modify the code to match those new descriptions,
- but we will preserve the existing enumerated values and their behavior for
- backward compatibility for that release.
-
- The fix for the problem described in note #2 will be shipped by OSF in Motif
- 1.2.2.
-
- SUMMARY
- We are sorry for any difficulty this causes Motif users. If you have any
- questions or flames (I suppose I deserve it) please send them directly to me.
- We sincerely hope this proactive response is better for our customers than you
- having to figure it out yourselves!
-
- Libby
-
-
- -----------------------------------------------------------------------------
- Subject: 123) What is IMUG and how do I join it?
-
- Answer: IMUG is the International Motif User Group founded by Quest Windows
- Corporation and co-sponsored by FedUNIX. IMUG is a non-profit organization
- working to keep users informed on technical and standards issues, to
- strengthen user groups on a local level, to increase communication among users
- internationally, and to promote the use of an international conference as a
- forum for sharing and learning more about Motif. You can join it by
-
- 1. Pay the annual membership fee of $20 USD directly to IMUG. Contact
-
- IMUG
- 5200 Great America Parkway
- Santa Clara, CA 95054
- (408) 496-1900
- imug@quest.com
-
- 2. Register at the International Motif User Conference, and automatically
- become an IMUG member.
-
- 3. Donate a pd widget, widget tool or widget builder to the IMUG Widget
- Depository and receive a free one year IMUG membership.
-
-
-
- -----------------------------------------------------------------------------
- Subject: 124) How do I set the title of a top level window?
- [Last modified: September 92]
-
- Answer: Set XmNtitle (and optionally XmNtitleEncoding) for TopLevelShells.
- (Note that this is of type String rather than XmStrin.) Ypu can also set
- XmNiconName if you want its icon to show this title. For XmDialogShells, set
- the XmNdialogTitle of its immediate child, assuming it's a BulletinBoard
- subclass. These can also be set in resource files.
-
-
- -----------------------------------------------------------------------------
- Subject: 125) Can I use editres with Motif?
- [Last modified: August 92]
-
- Answer: It isn't built in to Motif (at 1.2.0), but you can do this in your
- application
-
- extern void _XEditResCheckMessages();
- ...
- XtAddEventHandler(shell_widget, (EventMask)0, True,
- _XEditResCheckMessages, NULL);
-
- once for each shell widget that you want to react to the "click to select
- client" protocol. Then link your client with the R5 libXmu.
-
- David Brooks, OSF
-
-
- -----------------------------------------------------------------------------
- Subject: 126) How can I put decorations on transient windows using olwm?
-
- Answer: From Jean-Philippe Martin-Flatin <syj@ecmwf.co.uk>
-
- /**********************************************************************
- ** WindowDecorations.c
- **
- ** Manages window decorations under the OpenLook window manager (OLWM).
- **
- ** Adapted from a C++ program posted to comp.windows.x.motif by:
- **
- ** +--------------------------------------------------------------+
- ** | Ron Edmark User Interface Group |
- ** | Tel: (408) 980-1500 x282 Integrated Systems, Inc. |
- ** | Internet: edmark@isi.com 3260 Jay St. |
- ** | Voice mail: (408) 980-1590 x282 Santa Clara, CA 95054 |
- ** +--------------------------------------------------------------+
- ***********************************************************************/
-
- #include <X11/X.h>
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Protocols.h>
- #include <Xm/Xm.h>
- #include <Xm/AtomMgr.h>
-
- /*
- ** Decorations for OpenLook:
- ** The caller can OR different mask options to change the frame decoration.
- */
- #define OLWM_Header (long)(1<<0)
- #define OLWM_Resize (long)(1<<1)
- #define OLWM_Close (long)(1<<2)
-
- /*
- ** Prototypes
- */
- static void InstallOLWMAtoms (Widget w);
- static void AddOLWMDialogFrame(Widget widget, long decorationMask);
-
-
- /*
- ** Global variables
- */
- static Atom AtomWinAttr;
- static Atom AtomWTOther;
- static Atom AtomDecor;
- static Atom AtomResize;
- static Atom AtomHeader;
- static Atom AtomClose;
- static int not_installed_yet = TRUE;
-
-
- static void InstallOLWMAtoms(Widget w)
- {
- AtomWinAttr = XInternAtom(XtDisplay(w), "_OL_WIN_ATTR" , FALSE);
- AtomWTOther = XInternAtom(XtDisplay(w), "_OL_WT_OTHER", FALSE);
- AtomDecor = XInternAtom(XtDisplay(w), "_OL_DECOR_ADD", FALSE);
- AtomResize = XInternAtom(XtDisplay(w), "_OL_DECOR_RESIZE", FALSE);
- AtomHeader = XInternAtom(XtDisplay(w), "_OL_DECOR_HEADER", FALSE);
- AtomClose = XInternAtom(XtDisplay(w), "_OL_DECOR_CLOSE", FALSE);
-
- not_installed_yet = FALSE;
- }
-
- static void AddOLWMDialogFrame(Widget widget, long decorationMask)
- {
- Atom winAttrs[2];
- Atom winDecor[3];
- Widget shell = widget;
- Window win;
- int numberOfDecorations = 0;
-
- /*
- ** Make sure atoms for OpenLook are installed only once
- */
- if (not_installed_yet) InstallOLWMAtoms(widget);
-
- while (!XtIsShell(shell)) shell = XtParent(shell);
-
- win = XtWindow(shell);
-
- /*
- ** Tell Open Look that our window is not one of the standard OLWM window ** types. See OLIT Widget Set Programmer's Guide pp.70-73.
- */
-
- winAttrs[0] = AtomWTOther;
-
- XChangeProperty(XtDisplay(shell),
- win,
- AtomWinAttr,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char*)winAttrs,
- 1);
-
- /*
- ** Tell Open Look to add some decorations to our window
- */
- numberOfDecorations = 0;
- if (decorationMask & OLWM_Header)
- winDecor[numberOfDecorations++] = AtomHeader;
- if (decorationMask & OLWM_Resize)
- winDecor[numberOfDecorations++] = AtomResize;
- if (decorationMask & OLWM_Close)
- {
- winDecor[numberOfDecorations++] = AtomClose;
-
- /*
- ** If the close button is specified, the header must be
- ** specified. If the header bit is not set, set it.
- */
- if (!(decorationMask & OLWM_Header))
- winDecor[numberOfDecorations++] = AtomHeader;
- }
-
- XChangeProperty(XtDisplay(shell),
- win,
- AtomDecor,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char*)winDecor,
- numberOfDecorations);
- }
-
-
- /*
- ** Example of use of AddOLWMDialogFrame, with a bit of extra stuff
- */
- void register_dialog_to_WM(Widget shell, XtCallbackProc Cbk_func)
- {
- Atom atom;
-
- /*
- ** Alias the "Close" item in system menu attached to dialog shell
- ** to the activate callback of "Exit" in the menubar
- */
- if (Cbk_func)
- {
- atom = XmInternAtom(XtDisplay(shell),"WM_DELETE_WINDOW",TRUE);
- XmAddWMProtocolCallback(shell,atom, Cbk_func,NULL);
- }
-
- /*
- ** If Motif is the window manager, skip OpenLook specific stuff
- */
- if (XmIsMotifWMRunning(shell)) return;
-
- /*
- ** Register dialog shell to OpenLook.
- **
- ** WARNING: on some systems, adding the "Close" button allows the title
- ** to be properly centered in the title bar. On others, activating
- ** "Close" crashes OpenLook. The reason is not clear yet, but it seems
- ** the first case occurs with OpenWindows 2 while the second occurs with
- ** Openwindows 3. Thus, comment out one of the two following lines as
- ** suitable for your site, and send e-mail to syj@ecmwf.co.uk if you
- ** find out what is going on !
- */
- AddOLWMDialogFrame(shell,(OLWM_Header | OLWM_Resize));
- /* AddOLWMDialogFrame(shell,(OLWM_Header | OLWM_Resize | OLWM_Close)); */
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 127) Why does an augment translation appear to act as replace for
- some widgets? When I use either augment or override translations in
- .Xdefaults it seems to act as replace in both Motif 1.0 and 1.1
-
- Answer: By default, the translation table is NULL. If there is nothing
- specified (either in resource file, or in args), the widget's Initialize
- finds: Oh, there is NULL in translations, lets use our default ones. If,
- however, the translations have become non-NULL, the default translations are
- NOT used at all. Thus, using #augment, #override or a new table has identical
- effect: defines the new translations. The only way you can augment/override
- Motif's default translations is AFTER Initialize, using XtSetValues. Note,
- however, that Motif managers do play with translation tables as well ... so
- that results are not always easy to predict.
-
- From OSF: A number of people have complained about not being able to
- augment/override translations from the .Xdefaults. This is due to the
- complexity of the menu system/keyboard traversal and the necessary
- translations changes required to support the Motif Style Guide in menus. It
- cannot be fixed in a simple way. Fixing it requires re-design of the
- menus/buttons and it is planned to be fixed in 1.2.
-
-
-
-
-
- -----------------------------------------------------------------------------
- Subject: 128) How do you "grey" out a widget so that it cannot be activated?
-
- Answer: Use XtSetSensitive(widget, False). Do not set the XmNsensitive
- resource directly yourself (by XtSetValues) since the widget may need to talk
- to parents first.
-
-
- -----------------------------------------------------------------------------
- Subject: 129) Why doesn't the Help callback work on some widgets?
-
- Answer: If you press the help key the help callback of the widget with the
- keyboard focus is called (not the one containing the mouse). You can't get
- the help callback of a non-keyboard-selectable widget called. To get `context
- sensitive' help on these, you have to find the mouse, associate its position
- with a widget and then do the help.
-
-
-
- -----------------------------------------------------------------------------
- Subject: 130) Where can I get a Table widget?
-
- Answer: Send email to Kee Hinckley (nazgul@alfalfa.com) asking for a copy of
- his table widget. The Widget Creation Library also has one. See under Motif
- prototyping tools for the contact.
-
- Expert Database Systems, Inc., 305 Madison Ave, Suite 1166, New York, NY 10165
- has a very comprehensive table widget that uses both motif scrollbars or a
- "virtual" scrollbar showing a miniature version of the entire spreadsheet.
- Allows for different width columns, changing colors in each cell. Only one
- X-Window is used so as to reduce the amount of system resources used. Contact
- Ken Jones
-
-
- -----------------------------------------------------------------------------
- Subject: 131) Has anyone done a bar graph widget?
- [Last modified: September 92]
-
- Answer: You can fake one by using for each bar a scroll bar or even a label
- which changes in size, put inside a container of some kind.
-
- Try the StripChart widget in the Athena widget set. Set the XtNupdate resource
- to 0 to keep it from automatically updating.
-
- The comp.windows.x FAQ mentions a bar graph widget.
-
- Expert Database Systems, Inc. sells a bar graph widget as well as a multi-
- line graph with automatic scaling, a 3-D surface graph, and a high/Low graph
- with two lines for moving averages. Contact Ken Jones Expert Database
- Systems, Inc., 305 Madison Ave, Suite 1166, New York, NY 10165, Main Number:
- (212) 370-6700, Phone Mail: (212) 714-8345
-
- The Xtra XWidget library contains a set of widgets that are subclassed from
- and compatible with either OSF/Motif or OLIT widgets. The library includes
- widgets that implement the following:
-
- Spreadsheet
- Bar Graph
- Stacked Bar Graph
- Line Graph
- Pie Chart
- XY Plot
- Hypertext
- Hypertext based Help System
- Entry Form with type checking
-
- Contact Graphical Software Technology at 310-328-9338 (info@gst.com) for
- information.
-
- The XRT/graph widget, available for Motif, XView and OLIT, displays X-Y plots,
- bar and pie charts, and supports user-feedback, fast updates and PostScript
- output. Contact KL Group Inc. at 416-594-1026 (xrt_info%klg@uunet.ca)
-
- The product Xmath, made by Integrated Systems Inc. is a product which has
- interactive 2d and 3d graphics for bar,strip,line,symbol,
- surface,contour,etc... that costs $2500.00 for commercial use and a mere
- $250.00 for university use that also has complete numerics capabilities, an
- easy to use debugger, a complete high level language, a spreadsheet, a motif
- gui access capability, and much more all created on top of motif.
-
- You can either email to xmath-info@isi.com or call (408)980-1500.
-
- Digital Equipment Corporation (DEC) provides the following product NetEd: "The
- network editor widget is a Motif toolkit conforming widget that applications
- can use to express complex interrelationships graphically in the form of
- networks or graphs. The network editor supports interactive or application-
- controlled creation and editing of directed graphs or networks."
-
-
- ACE/gr is an X based XY plotting tool implemented with a point 'n click
- paradigm. A few of its features are:
-
- * Plots up to 10 graphs with 30 data sets per graph.
- * Data read from files and/or pipes.
- * Graph types XY, log-linear, linear-log, log-log, bar,
- stacked bar charts.
-
- it is available from
-
- ftp.ccalmr.ogi.edu (presently amb4.ccalmr.ogi.edu)
-
- with IP address 129.95.72.34. The XView version (xvgr) will be found in
- /CCALMR/pub/acegr/xvgr-2.09.tar.Z and the Motif version (xmgr) in
- /CCALMR/pub/acegr/xmgr-2.09.tar.Z. Comments, suggestions, bug reports to
- pturner@amb4.ccalmr.ogi.edu (if mail fails, try pturner@ese.ogi.edu). Due to
- time constraints, replies will be few and far between.
-
-
-
- -----------------------------------------------------------------------------
- Subject: 132) Does anyone know of a source code of a graph widget where you
- can add vertices and edges and get an automated updating?
-
- [Last modified: September 92]
-
- Answer: The XUG FAQ in comp.windows.x includes information on graph display
- widgets. There is also an implementation in the Asente/Swick book.
-
- From Martin Janzen: "You could have a look at DataViews, from V.I.
- Corporation. This package is used mainly to display a variety of graph
- drawings (eg. bar, line, pie, high/low, and other charts), and to update
- the graphs as information is received from "data sources" such as files,
- processes (through pipes), or devices.
-
- However, it also provides "node" and "edge" objects which can be used
- when working with network graphs. The DV-Tools function library
- provides routines which traverse a graph, count visits to each node or
- edge, mark nodes or edges of interest, and so on. A node or edge object
- can have an associated "geometry object" (such as a symbol or a line),
- which represents that node or edge.
-
- Drawbacks: There's no automatic positioning algorithm; when you add a
- node or edge, you have to create and position its geometry object
- yourself. Also, this isn't a set of add-on widgets; you can either have
- DataViews create an X window (ie. a separate shell), or you can create
- your own XmDrawingArea and use DataViews to update its window when
- expose events are received. Finally, the package is quite expensive,
- and there is a run-time charge.
-
- The vendor's address is:
- V.I. Corporation,
- 47 Pleasant Street,
- Northampton, MA 01060,
- Email: vi@vicorp.com, Phone: (413) 586-4144, Fax: (413) 584-2649
-
- or
-
- V.I. Corporation (Europe) Ltd.,
- First Base, Beacontree Plaza,
- Gillette Way, Email: viesales@eurovi.uucp
- Reading, Berkshire RG2 0BP"
- Phone: +44 734 756010, Fax: +44 734 756104
-
- From Craig Timmerman: Just wanted others to know that there is a third
- competitor in what may be come a big market for generic APIs. The product is
- called Open Interface and Neuron Data is the vendor. Neuron has added some
- extra, more complex widgets to their set. The two most notable are a table
- and network widget. [...] I believe that the network widget got its name from
- its ability to display expert system networks that Neuron's AI tools needed.
- It would be more aptly named the graph widget. It can display and manipulate
- graphs of various types (trees, directed graphs, etc). Contact is
-
- Neuron Data
- 156 University Avenue
- Palo Alto, CA 94301
- (415) 321-4488
-
-
- prism!gt3273b@gatech.edu (RENALDS,ANDREW THEODORE) posted a set of public
- domain routines for graph drawing. Contact him for a later set.
-
- From Ramon Santiago (santiago@fgssu1.fgs.slb.com): HP has released source code
- for XmGraph and XmArc, part of the InterWorks library, which does exactly
- this. The sources can be obtained by contacting Dave Shaw,
- librarian@iworks.ecn.uiowa.edu. A few trivial source code changes need to be
- made to get these widgets to compile under Motif 1.2.
-
-
- -----------------------------------------------------------------------------
- Subject: 133) Is there a help system available, such as in Windows 3? Or any
- Motif based hypertext system.
-
- Answer:
-
- Bristol Technology have a hypertext system HyperHelp with the look-and-feel of
- either Motif or OpenLook. It should be available from january 31, 1992.
- Contact
-
- Bristol Technology Inc.
- 898 Ethan Allen Highway
- Ridgefield, CT 06877
- 203-438-6969 (phone)
- 203-438-5013 (fax)
- uunet.uu.net!bristol!keith
-
- Demos are available by anonymous ftp from ftp.uu.net (137.39.1.9) in the
- vendor/Bristol/HyperHelp as files sun.motif.tar.Z and hp.tar.Z.
-
- There was a posting of a motif hypertext-widget to comp.sources.x (Author:
- B.Raoult ( mab@ecmwf.co.uk ) ). It had the facility to read in helptext from
- a file.
-
- From Francois Felix Ingrand (felix@idefix.laas.fr): I have translated the Info
- AW (originally written by Jordan Hubbard) to Motif. It is a Widget to browse
- Info files (format used by GNU for their various documentations). I use it as
- the help system of various tool I wrote. It is available on laas.laas.fr
- (140.93.0.15) in /pub/prs/xinfo-motif.tar.Z
-
- Form Scott Raney (raney@metacard.com) MetaCard is a commercial package that
- can be used to implement hypertext help. The text fields support multiple
- typefaces, sizes, styles, colors, subscript/superscript, and hypertext links.
- It has a Motif interface, and a template for calling it from an Xt/Motif
- application is included. You can FTP a save-disabled distribution from
- ftp.metacard.com or from world.std.com. For more info, email to
- info@metacard.com.
-
-
-
-
- -----------------------------------------------------------------------------
- Subject: 134) Can I specify a widget in a resource file?
-
- Answer: This answer, which uses the Xmu library, is due to David Elliott. If
- the converter is added, then the name of a widget (a string) can be used in
- resource files, and will be converted to the appropriate widget.
-
- This code, which was basically stolen from the Athena Form widget, adds a
- String to Widget converter. I wrote it as a general routine that I call at
- the beginning of all of my programs, and made it so I could add other
- converters as needed (like String to Unit Type ;-).
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <Xm/Xm.h>
- #include <X11/Xmu/Converters.h>
- #include <X11/IntrinsicP.h>
- #include <X11/CoreP.h>
-
- void
- setupConverters()
- {
- static XtConvertArgRec parentCvtArgs[] = {
- {XtBaseOffset, (caddr_t)XtOffset(Widget, core.parent),
- sizeof(Widget)}
- };
-
- XtAddConverter(XmRString, XmRWindow, XmuCvtStringToWidget,
- parentCvtArgs, XtNumber(parentCvtArgs));
- }
-
-
-
- -----------------------------------------------------------------------------
- Subject: 135) Why are only some of my translations are being installed? I
- have a translation table like the following, but only the first ones are
- getting installed and the rest are ignored.
-
- *Text.translations: #override \
- Ctrl<Key>a: beginning-of-line() \n\
- Ctrl<Key>e: end-of-line() \n\
- Ctrl<Key>f: forward-character() \n\
-
-
- Answer: Most likely, you have a space at the end of one of the lines (the
- first in this case).
-
- Ctrl<Key>a: beginning-of-line() \n\
- ^ space here
-
- The second backslash in each line is there to protect the real newline
- character and so you must not follow it with anything other than the newline
- itself. Otherwise it acts as the end of the resource definition and the
- remaining lines are not added.
-
-
- -----------------------------------------------------------------------------
- Subject: 136) Where can I get the PanHandler code?
-
- Answer: It is available by email from Chuck Ocheret: chuck@IMSI.COM.
-
- -----------------------------------------------------------------------------
- Subject: 137) What are these passive grab warnings? When I destroy certain
- widgets I get a stream of messages
-
- Warning: Attempt to remove non-existant passive grab
-
-
- Answer: They are meaningless, and you want to ignore them. Do this (from Kee
- Hinckley) by installing an XtWarning handler that explicitly looks for them
- and discards them:
-
- static void xtWarnCB(String message) {
- if (asi_strstr(message, "non-existant passive grab", TRUE)) return;
- ...
-
- They come from Xt, and (W. Scott Meeks): "it's something that the designers of
- Xt decided the toolkit should do. Unfortunately, Motif winds up putting
- passive grabs all over the place for the menu system. On the one hand, we
- want to remove all these grabs when menus get destroyed so that they don't
- leak memory; on the other hand, it's almost impossible to keep track of all
- the grabs, so we have a conservative strategy of ungrabbing any place where a
- grab could have been made and we don't explicitly know that there is no grab.
- The unfortunate side effect is the little passive grab warning messages.
- We're trying to clean these up where possible, but there are some new places
- where the warning is generated. Until we get this completely cleaned up (1.2
- maybe), your best bet is probably to use a warning handler."
-
- -----------------------------------------------------------------------------
- Subject: 138) How do I have more buttons than three in a box? I want to have
- something like a MessageBox (or other widget) with more than three buttons,
- but with the same nice appearance.
-
- Answer: A SelectionBox is created with four buttons, but the fourth (the Apply
- button) is unmanaged. To manage it get its widget ID via
- XmSelectionBoxGetChild(parent, XmDIALOG_APPLY_BUTTON) and then XtManage it.
- Unmanage all of the other bits in the SelectionBox that you don't want. If
- you want more than four buttons, try two SelectionBoxes (or similar) together
- in a container, where all of the unwanted parts of the widgets are unmanaged.
-
- Alternatively, build your own dialog:
-
- /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates.
- * This program is freely distributable without licensing fees and
- * is provided without guarantee or warranty expressed or implied.
- * This program is -not- in the public domain. This program is
- * taken from the Motif Programming Manual, O'Reilly Volume 6.
- */
-
- /* action_area.c -- demonstrate how CreateActionArea() can be used
- * in a real application. Create what would otherwise be identified
- * as a PromptDialog, only this is of our own creation. As such,
- * we provide a TextField widget for input. When the user presses
- * Return, the Ok button is activated.
- */
- #include <Xm/DialogS.h>
- #include <Xm/PushBG.h>
- #include <Xm/PushB.h>
- #include <Xm/LabelG.h>
- #include <Xm/PanedW.h>
- #include <Xm/Form.h>
- #include <Xm/RowColumn.h>
- #include <Xm/TextF.h>
-
- typedef struct {
- char *label;
- void (*callback)();
- caddr_t data;
- } ActionAreaItem;
-
- static void
- do_dialog(), close_dialog(), activate_cb(),
- ok_pushed(), cancel_pushed(), help();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- Widget toplevel, button;
- XtAppContext app;
-
- toplevel = XtVaAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL);
-
- button = XtVaCreateManagedWidget("Push Me",
- xmPushButtonWidgetClass, toplevel, NULL);
- XtAddCallback(button, XmNactivateCallback, do_dialog, NULL);
-
- XtRealizeWidget(toplevel);
- XtAppMainLoop(app);
- }
-
- /* callback routine for "Push Me" button. Actually, this represents
- * a function that could be invoked by any arbitrary callback. Here,
- * we demonstrate how one can build a standard customized dialog box.
- * The control area is created here and the action area is created in
- * a separate, generic routine: CreateActionArea().
- */
- static void
- do_dialog(w, file)
- Widget w; /* will act as dialog's parent */
- char *file;
- {
- Widget dialog, pane, rc, label, text_w, action_a;
- XmString string;
- extern Widget CreateActionArea();
- Arg args[10];
- static ActionAreaItem action_items[] = {
- { "Ok", ok_pushed, NULL },
- { "Cancel", cancel_pushed, NULL },
- { "Close", close_dialog, NULL },
- { "Help", help, "Help Button" },
- };
-
- /* The DialogShell is the Shell for this dialog. Set it up so
- * that the "Close" button in the window manager's system menu
- * destroys the shell (it only unmaps it by default).
- */
- dialog = XtVaCreatePopupShell("dialog",
- xmDialogShellWidgetClass, XtParent(w),
- XmNtitle, "Dialog Shell", /* give arbitrary title in wm */
- XmNdeleteResponse, XmDESTROY, /* system menu "Close" action */
- NULL);
-
- /* now that the dialog is created, set the Close button's
- * client data, so close_dialog() will know what to destroy.
- */
- action_items[2].data = (caddr_t)dialog;
-
- /* Create the paned window as a child of the dialog. This will
- * contain the control area (a Form widget) and the action area
- * (created by CreateActionArea() using the action_items above).
- */
- pane = XtVaCreateWidget("pane", xmPanedWindowWidgetClass, dialog,
- XmNsashWidth, 1,
- XmNsashHeight, 1,
- NULL);
-
- /* create the control area (Form) which contains a
- * Label gadget and a List widget.
- */
- rc = XtVaCreateWidget("control_area", xmRowColumnWidgetClass, pane, NULL);
- string = XmStringCreateSimple("Type Something:");
- XtVaCreateManagedWidget("label", xmLabelGadgetClass, rc,
- XmNlabelString, string,
- XmNleftAttachment, XmATTACH_FORM,
- XmNtopAttachment, XmATTACH_FORM,
- NULL);
- XmStringFree(string);
-
- text_w = XtVaCreateManagedWidget("text-field",
- xmTextFieldWidgetClass, rc, NULL);
-
- /* RowColumn is full -- now manage */
- XtManageChild(rc);
-
- /* Set the client data "Ok" and "Cancel" button's callbacks. */
- action_items[0].data = (caddr_t)text_w;
- action_items[1].data = (caddr_t)text_w;
-
- /* Create the action area -- we don't need the widget it returns. */
- action_a = CreateActionArea(pane, action_items, XtNumber(action_items));
-
- /* callback for Return in TextField. Use action_a as client data */
- XtAddCallback(text_w, XmNactivateCallback, activate_cb, action_a);
-
- XtManageChild(pane);
- XtPopup(dialog, XtGrabNone);
- }
-
- /*--------------*/
- /* The next four functions are the callback routines for the buttons
- * in the action area for the dialog created above. Again, they are
- * simple examples, yet they demonstrate the fundamental design approach.
- */
- static void
- close_dialog(w, shell)
- Widget w, shell;
- {
- XtDestroyWidget(shell);
- }
-
- /* The "ok" button was pushed or the user pressed Return */
- static void
- ok_pushed(w, text_w, cbs)
- Widget w, text_w; /* the text widget is the client data */
- XmAnyCallbackStruct *cbs;
- {
- char *text = XmTextFieldGetString(text_w);
-
- printf("String = %s0, text);
- XtFree(text);
- }
-
- static void
- cancel_pushed(w, text_w, cbs)
- Widget w, text_w; /* the text field is the client data */
- XmAnyCallbackStruct *cbs;
- {
- /* cancel the whole operation; reset to NULL. */
- XmTextFieldSetString(text_w, "");
- }
-
- static void
- help(w, string)
- Widget w;
- String string;
- {
- puts(string);
- }
- /*--------------*/
-
- /* When Return is pressed in TextField widget, respond by getting
- * the designated "default button" in the action area and activate
- * it as if the user had selected it.
- */
- static void
- activate_cb(text_w, client_data, cbs)
- Widget text_w; /* user pressed Return in this widget */
- XtPointer client_data; /* action_area passed as client data */
- XmAnyCallbackStruct *cbs; /* borrow the "event" field from this */
- {
- Widget dflt, action_area = (Widget)client_data;
-
- XtVaGetValues(action_area, XmNdefaultButton, &dflt, NULL);
- if (dflt) /* sanity check -- this better work */
- /* make the default button think it got pushed. This causes
- * "ok_pushed" to be called, but XtCallActionProc() causes
- * the button appear to be activated as if the user selected it.
- */
- XtCallActionProc(dflt, "ArmAndActivate", cbs->event, NULL, 0);
- }
-
- #define TIGHTNESS 20
-
- Widget
- CreateActionArea(parent, actions, num_actions)
- Widget parent;
- ActionAreaItem *actions;
- int num_actions;
- {
- Widget action_area, widget;
- int i;
-
- action_area = XtVaCreateWidget("action_area", xmFormWidgetClass, parent,
- XmNfractionBase, TIGHTNESS*num_actions - 1,
- XmNleftOffset, 10,
- XmNrightOffset, 10,
- NULL);
-
- for (i = 0; i < num_actions; i++) {
- widget = XtVaCreateManagedWidget(actions[i].label,
- xmPushButtonWidgetClass, action_area,
- XmNleftAttachment, i? XmATTACH_POSITION : XmATTACH_FORM,
- XmNleftPosition, TIGHTNESS*i,
- XmNtopAttachment, XmATTACH_FORM,
- XmNbottomAttachment, XmATTACH_FORM,
- XmNrightAttachment,
- i != num_actions-1? XmATTACH_POSITION : XmATTACH_FORM,
- XmNrightPosition, TIGHTNESS*i + (TIGHTNESS-1),
- XmNshowAsDefault, i == 0,
- XmNdefaultButtonShadowThickness, 1,
- NULL);
- if (actions[i].callback)
- XtAddCallback(widget, XmNactivateCallback,
- actions[i].callback, actions[i].data);
- if (i == 0) {
- /* Set the action_area's default button to the first widget
- * created (or, make the index a parameter to the function
- * or have it be part of the data structure). Also, set the
- * pane window constraint for max and min heights so this
- * particular pane in the PanedWindow is not resizable.
- */
- Dimension height, h;
- XtVaGetValues(action_area, XmNmarginHeight, &h, NULL);
- XtVaGetValues(widget, XmNheight, &height, NULL);
- height += 2 * h;
- XtVaSetValues(action_area,
- XmNdefaultButton, widget,
- XmNpaneMaximum, height,
- XmNpaneMinimum, height,
- NULL);
- }
- }
-
- XtManageChild(action_area);
-
- return action_area;
- }
-
-
-
- -----------------------------------------------------------------------------
- Subject: 139) How do I create a "busy working cursor"?
-
- Answer: - in Baudouin's code (following), the idea is to keep in an array an
- up-to-date list of all shells used in the application, and set for all of them
- the cursor to a watch or to the default cursor, with the 2 functions provided.
-
- - in Dan Heller's code (later), the idea is to turn on the watch cursor for
- the top-level shell only, popup a working window to possibly abort the
- callback, and manage some expose events during the callback.
-
- - in the FAQ for comp.windows.x (#113), the idea is to bring a large window on
- top of the application, hide all windows below it, and turn on the watch
- cursor on this large window. Unmapping the large window resets the default
- cursor, mapping it turns on the watch cursor.
-
- From Baudouin Raoult (mab@ecmwf.co.uk)
-
- void my_SetWatchCursor(w)
- Widget w;
- {
- static Cursor watch = NULL;
-
- if(!watch)
- watch = XCreateFontCursor(XtDisplay(w),XC_watch);
-
- XDefineCursor(XtDisplay(w),XtWindow(w),watch);
- XmUpdateDisplay(w);
- }
-
- void my_ResetCursor(w)
- Widget w;
- {
- XUndefineCursor(XtDisplay(w),XtWindow(w));
- XmUpdateDisplay(w);
- }
-
-
- Answer: A solution with lots of bells and whistles is
-
- /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates.
- * This program is freely distributable without licensing fees and
- * is provided without guarantee or warrantee expressed or implied.
- * This program is -not- in the public domain.
- */
-
- /* busy.c -- demonstrate how to use a WorkingDialog and to process
- * only "important" events. e.g., those that may interrupt the
- * task or to repaint widgets for exposure. Set up a simple shell
- * and a widget that, when pressed, immediately goes into its own
- * loop. First, "lock" the shell so that a timeout cursor is set on
- * the shell and pop up a WorkingDialog. Then enter loop ... sleep
- * for one second ten times, checking between each interval to see
- * if the user clicked the Stop button or if any widgets need to be
- * refreshed. Ignore all other events.
- *
- * main() and get_busy() are stubs that would be replaced by a real
- * application; all other functions can be used "as is."
- */
- #include <Xm/MessageB.h>
- #include <Xm/PushB.h>
- #include <X11/cursorfont.h>
-
- Widget shell;
- void TimeoutCursors();
- Boolean CheckForInterrupt();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- XtAppContext app;
- Widget button;
- XmString label;
- void get_busy();
-
- shell = XtVaAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL);
-
- label = XmStringCreateSimple(
- "Boy, is *this* going to take a long time.");
- button = XtVaCreateManagedWidget("button",
- xmPushButtonWidgetClass, shell,
- XmNlabelString, label,
- NULL);
- XmStringFree(label);
- XtAddCallback(button, XmNactivateCallback, get_busy, argv[1]);
-
- XtRealizeWidget(shell);
- XtAppMainLoop(app);
- }
-
- void
- get_busy(widget)
- Widget widget;
- {
- int n;
-
- TimeoutCursors(True, True);
- for (n = 0; n < 10; n++) {
- sleep(1);
- if (CheckForInterrupt()) {
- puts("Interrupt!");
- break;
- }
- }
- if (n == 10)
- puts("done.");
- TimeoutCursors(False, NULL);
- }
-
- /* The interesting part of the program -- extract and use at will */
- static Boolean stopped; /* True when user wants to stop processing */
- static Widget dialog; /* WorkingDialog displayed when timed out */
-
- /* timeout_cursors() turns on the "watch" cursor over the application
- * to provide feedback for the user that he's going to be waiting
- * a while before he can interact with the appliation again.
- */
- void
- TimeoutCursors(on, interruptable)
- int on, interruptable;
- {
- static int locked;
- static Cursor cursor;
- extern Widget shell;
- XSetWindowAttributes attrs;
- Display *dpy = XtDisplay(shell);
- XEvent event;
- Arg args[1];
- XmString str;
- extern void stop();
-
- /* "locked" keeps track if we've already called the function.
- * This allows recursion and is necessary for most situations.
- */
- on? locked++ : locked--;
- if (locked > 1 || locked == 1 && on == 0)
- return; /* already locked and we're not unlocking */
-
- stopped = False; /* doesn't matter at this point; initialize */
- if (!cursor) /* make sure the timeout cursor is initialized */
- cursor = XCreateFontCursor(dpy, XC_watch);
-
- /* if "on" is true, then turn on watch cursor, otherwise, return
- * the shell's cursor to normal.
- */
- attrs.cursor = on? cursor : None;
-
- /* change the main application shell's cursor to be the timeout
- * cursor (or to reset it to normal). If other shells exist in
- * this application, they will have to be listed here in order
- * for them to have timeout cursors too.
- */
- XChangeWindowAttributes(dpy, XtWindow(shell), CWCursor, &attrs);
-
- XFlush(dpy);
-
- if (on) {
- /* we're timing out, put up a WorkingDialog. If the process
- * is interruptable, allow a "Stop" button. Otherwise, remove
- * all actions so the user can't stop the processing.
- */
- str = XmStringCreateSimple("Busy. Please Wait.");
- XtSetArg(args[0], XmNmessageString, str);
- dialog = XmCreateWorkingDialog(shell, "Busy", args, 1);
- XmStringFree(str);
- XtUnmanageChild(
- XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
- if (interruptable) {
- str = XmStringCreateSimple("Stop");
- XtVaSetValues(dialog, XmNcancelLabelString, str, NULL);
- XmStringFree(str);
- XtAddCallback(dialog, XmNcancelCallback, stop, NULL);
- } else
- XtUnmanageChild(
- XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
- XtUnmanageChild(
- XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
- XtManageChild(dialog);
- } else {
- /* get rid of all button and keyboard events that occured
- * during the time out. The user shouldn't have done anything
- * during this time, so flush for button and keypress events.
- * KeyRelease events are not discarded because accelerators
- * require the corresponding release event before normal input
- * can continue.
- */
- while (XCheckMaskEvent(dpy,
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | PointerMotionMask | KeyPressMask, &event)) {
- /* do nothing */;
- }
- XtDestroyWidget(dialog);
- }
- }
-
- /* User Pressed the "Stop" button in dialog. */
- void
- stop(dialog)
- Widget dialog;
- {
- stopped = True;
- }
-
- Boolean
- CheckForInterrupt()
- {
- extern Widget shell;
- Display *dpy = XtDisplay(shell);
- Window win = XtWindow(dialog);
- XEvent event;
-
- /* Make sure all our requests get to the server */
- XFlush(dpy);
-
- /* Let motif process all pending exposure events for us. */
- XmUpdateDisplay(shell);
-
- /* Check the event loop for events in the dialog ("Stop"?) */
- while (XCheckMaskEvent(dpy,
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
- PointerMotionMask | KeyPressMask | KeyReleaseMask,
- &event)) {
- /* got an "interesting" event. */
- if (event.xany.window == win)
- XtDispatchEvent(&event); /* it's in our dialog.. */
- else /* uninteresting event--throw it away and sound bell */
- XBell(dpy, 50);
- }
- return stopped;
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 140) What order should the libraries be linked in?
- [Last modified: August 92]
-
- Answer: At link time, use the library order -lXm -lXt -lX11. There are two
- reasons for this (dbrooks@osf.org):
-
- On most systems, the order matters because the linker won't re-scan a library
- once it is done with it. Thus any references to Xlib calls from Xm will
- probably be unresolved.
-
- The [other] problem is that there are two VendorShell widgets. A dummy is
- provided in the Xt library, but a widget set will rely on its own being
- referenced. If you mention Xt first, the linker will choose the wrong one.
-
- Motif code will wrongly assume the Motif VendorShell has been class-
- initialized [and will probably crash].
- Xaw has a similar problem, but a softer landing; it only complains about
- unregistered converters.
-
-
- -----------------------------------------------------------------------------
- Subject: 141) How do I use xmkmf for Motif clients?
-
- [Last modified: October 1992]
-
- Answer: This advice comes from dbrooks@osf.org:
-
- There are a number of intractable problems with using X configuration files
- and xmkmf, while trying to make it easy to build Motif. Not the least of
- these, but one I've never heard mentioned yet, is that the rules for
- contructing the names of shared library macros are machine-dependent, and in
- the various xxxLib.tmpl files. Do we edit all those files to add definitions
- for XMLIB, DEPXMLIB, etc., or do we put a maze of #ifdefs into the Motif.tmpl
- file?
-
- Please note that, if you install Motif, it overwrites your installed
- Imake.tmpl with one that includes Motif.tmpl and Motif.rules.
-
- With those caveats, I think the following guidelines will help.
-
- David Brooks OSF
-
- Clients in the X11R5 release use the xmkmf command to build Makefiles. In
- general, the xmkmf command cannot be used for Motif clients, because of the
- need to consider the UseInstalledMotif flag separately. Since xmkmf is a
- simple script that calls imake, it is easy to construct the proper call to
- imake using the following rules.
-
- In the following, replace {MTOP} by the toplevel directory with the Motif
- source tree, and {XTOP} by the toplevel ("mit") directory with the X source.
- It is assumed that the directory containing your installed imake is in your
- PATH.
-
- When needed, the imake variables XTop and MTop are normally set in your
- site.def (to {XTOP} amd {MTOP} respectively); however they may also be set
- with additional -D arguments to imake.
-
- 1. With both X and Motif in their source trees, ensure the imake variables
- XTop and MTop are set, and use:
-
- ${XTOP}/config/imake -I{MTOP}/config
-
- 2. With Motif in its source tree, and X installed, ensure MTop is set, and
- use:
-
- imake -I{MTOP}/config -DUseInstalled
-
- 3. With both Motif and X installed, and a nonstandard ProjectRoot (see
- site.def for an explanation of this), use:
-
- imake -DUseInstalled -DUseInstalledMotif -I{ProjectRoot}/lib/X11/config
-
- or, if the configuration files are in /usr/lib/X11/config:
-
- imake -DUseInstalled -DUseInstalledMotif
-
-
- To build a simple Imakefile, remember to include lines like this:
-
- LOCAL_LIBRARIES = XmClientLibs
- DEPLIBS = XmClientDepLibs
-
- Or, for a client that uses uil/mrm, replace these by MrmClientLibs and
- MrmClientDepLibs, and also use:
-
- MSimpleUilTarget(program)
-
- to build the client and uid file. Look at the demos for more examples.
-
-
- And Paul Howell <grue@engin.umich.edu> added:
-
- i did this, calling the new script "xmmkmf". It passes both -DUseInstalled
- and -DUseInstalledMotif.
-
- and i modified the stock R5 Imake.tmpl to do this:
-
- #include <Project.tmpl>
- #ifdef UseInstalledMotif
- #include <Motif.tmpl>
- #endif
-
- #include <Imake.rules>
- #ifdef UseInstalledMotif
- #include <Motif.rules>
- #endif
-
- the result was something that does both athena and motif rules. and it really
- works, just that easy!
-
-
- -----------------------------------------------------------------------------
- Subject: 142) How do I make context sensitive help? The Motif Style Guide
- says that an application must initiate context-sensitive help by changing the
- shape of the pointer to the question pointer. When the user moves the pointer
- to the component help is wanted on and presses BSelect, any available context
- sensitive help for the component must be presented, and the pointer reverts
- from the question pointer.
- [Last modified: August 92]
-
- Answer: A widget that gives context sensitive help would place this help in
- the XmNhelpCallback function. To trigger this function: (from Martin G C
- Davies, mgcd@se.alcbel.be)
-
- I use the following callback that is called when the "On Context" help
- pulldown menu is selected. It does the arrow bit and calls the help callbacks
- for the widget. It also zips up the widget tree looking for help if needs be.
- I don't restrict the arrows motion so I can get help on dialog boxes. No
- prizes for guessing what "popup_message" does.
-
-
- static void ContextHelp(
- Widget w ,
- Opaque * tag ,
- XmAnyCallbackStruct * callback_struct
- )
- {
- static Cursor context_cursor = NULL ;
- Widget context_widget ;
-
- if ( context_cursor == NULL )
- context_cursor = XCreateFontCursor( display, XC_question_arrow ) ;
-
- context_widget = XmTrackingLocate( top_level_widget,
- context_cursor, FALSE ) ;
-
- if ( context_widget != NULL ) /* otherwise its not a widget */
- {
- XmAnyCallbackStruct cb ;
-
- cb.reason = XmCR_HELP ;
- cb.event = callback_struct->event ;
-
- /*
- * If there's no help at this widget we'll track back
- up the hierarchy trying to find some.
- */
-
- do
- {
- if ( ( XtHasCallbacks( context_widget, XmNhelpCallback ) ==
- XtCallbackHasSome ) )
- {
- XtCallCallbacks( context_widget, XmNhelpCallback, & cb ) ;
- return ;
- }
- else
- context_widget = XtParent( context_widget ) ;
- } while ( context_widget != NULL ) ;
- }
-
- popup_message( "No context-sensitive help found\n\
- for the selected object." ) ;
- }
-
-
-
- Dave Bonnett suggested, to use the following translations for XmText (and
- XmTextField) widgets to get the same help with key strokes, and to provide an
- accelerator label in the Context help menu entry.
-
- MyApp*XmText*translations: #override\n\
- <Key>F1: Help()
-
- MyApp*Help_menu*Contextual Help.acceleratorText: F1
-
- MyApp*defaultVirtualBindings: osfBackSpace : <Key>Delete\n\
- osfRight : <Key>Right\n\
- osfLeft : <Key>Left\n\
- osfUp : <Key>Up\n\
- osfHelp : <Key>F1\n\
- osfDown : <Key>Down
-
- -----------------------------------------------------------------------------
- Subject: 143) TOPIC: ACKNOWLEDGEMENTS
-
- This list was compiled using questions and answers posed to
- comp.windows.x.motif and motif-talk. Some extracts were also taken from FAQs
- of comp.windows.x. To all who contributed one way or the other, thanks! I
- haven't often given individual references, but you may recognise
- contributions. If I have mangled them too much, let me know.
-
-
-
- That's all folks!
-
-
- +----------------------+---+
- Jan Newmarch, Information Science and Engineering,
- University of Canberra, PO Box 1, Belconnen, Act 2616
- Australia. Tel: (Aust) 6-2522422. Fax: (Aust) 6-2522999
-
- ACSnet: jan@ise.canberra.edu.au
- ARPA: jan%ise.canberra.edu.au@uunet.uu.net
- UUCP: {uunet,ukc}!munnari!ise.canberra.edu.au!jan
- JANET: jan%au.edu.canberra.ise@EAN-RELAY
-
- +--------------------------+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Local Variables:
- mode: outline
- outline-regexp: "Subject: +[0-9]+)"
- eval: (hide-body)
- End:
- --
- +----------------------+---+
- Jan Newmarch, Information Science and Engineering,
- University of Canberra, PO Box 1, Belconnen, Act 2616
- Australia. Tel: (Aust) 6-2012422. Fax: (Aust) 6-2015041
-